package cn.lan.generator.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.lan.generator.bean.EntityAttrInfo;
import cn.lan.generator.bean.EntityInfo;
import cn.lan.generator.bean.Module;
import cn.lan.generator.bean.ProjInfo;
import cn.lan.generator.service.CreateFile;
import cn.lan.generator.utils.ConfigUtil;
import cn.lan.generator.utils.Constant;
import cn.lan.generator.utils.FileUtil;
import cn.lan.generator.utils.StringUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lanping
 * @version 1.0
 * @date 2019-07-06
 **/
public class CreateServiceImplFileImpl implements CreateFile {

    /**
     * 创建接口实现文件
     *
     * @param entityInfo 实体名
     * @param projInfo   项目信息
     * @return
     * @throws Exception
     */
    @Override
    public void writeFile(EntityInfo entityInfo, ProjInfo projInfo) throws Exception {

        String tableComment = entityInfo.getTableComment();
        String lowerPrimaryKey = StringUtil.toLowerCaseFirstOne(entityInfo.getPrimaryKey());
        String upperPrimaryKey = StringUtil.toUpperCaseFirstOne(entityInfo.getPrimaryKey());
        String primaryKeyType = entityInfo.getPrimaryKeyType();

        String upperEntityName = StringUtil.toUpperCaseFirstOne(entityInfo.getEntityName());
        String lowerEntityName = StringUtil.toLowerCaseFirstOne(entityInfo.getEntityName());

        String packageName = ConfigUtil.getServiceImplPackage(projInfo);
        String entityPackName = ConfigUtil.getEntityPackage(projInfo);
        String enumsPackage = ConfigUtil.getEnumsPackage(projInfo.getPackageName());
        String exceptionPackName = ConfigUtil.getExceptionPackage(projInfo.getPackageName());
        String validatePackName = ConfigUtil.getValidatePackage(projInfo.getPackageName());
        String utilsPackage = ConfigUtil.getCommonUtilsPackage(projInfo.getPackageName());
        String mapperPackage = ConfigUtil.getMapperPackage(projInfo);
        String servicePackage = ConfigUtil.getServicePackage(projInfo);
        String dtoPackName = ConfigUtil.getDtoPackage(projInfo);
        String listDtoPackage = ConfigUtil.getListDtoPackage(projInfo);
        String voPackName = ConfigUtil.getVoPackage(projInfo);
        String commonBeanPackage = ConfigUtil.getCommonBeanPackage(projInfo.getPackageName());

        String srcFilePath =FileUtil.getResourceRootDir(projInfo.isDebugModel())+Constant.TEMPLATE_SERVICE_IMPL_PATH;

        String suffixPath = packageName.replaceAll("\\.", "\\\\") + "\\" + upperEntityName + "ServiceImpl" + Constant.FILE_SUFFIX_JAVA;
        String destFilePath = Constant.getFilePath(projInfo, Module.getModule(projInfo).getService(),  Constant.PathType.basePath, suffixPath);

        String updatePrimaryTypeStr= lowerPrimaryKey;
        if("Integer".equals(primaryKeyType)){
            updatePrimaryTypeStr = "Integer.parseInt("+lowerPrimaryKey+")";
        }else if("Long".equals(primaryKeyType)){
            updatePrimaryTypeStr = "Long.parseLong("+lowerPrimaryKey+")";
        }else if("Double".equals(primaryKeyType)){
            updatePrimaryTypeStr = "Double.parseDouble("+lowerPrimaryKey+")";
        }else if("String".equals(primaryKeyType)){
            updatePrimaryTypeStr = lowerPrimaryKey;
        }

        final String updatePrimaryType = updatePrimaryTypeStr;
        String setValStr = "";
        /*if("String".equals(primaryKeyType)){
            setValStr+= "\n\t\t\tif(ObjectUtil.isEmpty("+lowerEntityName+".get"+upperPrimaryKey+"())){\n"
                    +"\t\t\t\t"+lowerEntityName+".set"+upperPrimaryKey+"(UUID.fastUUID().toString(true));\n"+
                    "\t\t\t}";
        }*/

        String validateAttrName = "";
        String setDateKey = "";
        boolean hasDate=false;
        boolean hasHutoolDate=false;

        for (EntityAttrInfo entityAttrInfo:entityInfo.getEntityAttrs()){
            String attrName = entityAttrInfo.getAttrName();
            String dataType = entityAttrInfo.getDataType();
            String attrType = entityAttrInfo.getAttrType();
            String uppAttrName = StringUtil.toUpperCaseFirstOne(attrName);
            if("date".equalsIgnoreCase(dataType) || "datetime".equalsIgnoreCase(dataType)
                    || "json".equalsIgnoreCase(dataType)){
                //处理
                validateAttrName+="\n\t\tif(ObjectUtil.isEmpty("+lowerEntityName+".get"+uppAttrName+"())){";
                validateAttrName+="\n\t\t\t"+lowerEntityName+".set"+uppAttrName+"(null);";
                validateAttrName+="\n\t\t}";
            }
            if("state".equals(attrName)){
                if("String".equals(attrType)){
                    setValStr+="\n\t\t\tif(ObjectUtil.isEmpty("+lowerEntityName+".get"+uppAttrName+"())){";
                    setValStr+="\n\t\t\t\t"+lowerEntityName+".set"+uppAttrName+"(ConstantUtil.IS_VALID_Y);";
                    setValStr+="\n\t\t\t}";
                }else if("Integer".equals(attrType)){
                    setValStr+="\n\t\t\tif(ObjectUtil.isEmpty("+lowerEntityName+".get"+uppAttrName+"())){";
                    setValStr+="\n\t\t\t\t"+lowerEntityName+".set"+uppAttrName+"(0);";
                    setValStr+="\n\t\t\t}";
                }
            }else if("createTime".equals(attrName)){
                if("String".equals(attrType)){
                    setValStr+="\n\t\t\t"+lowerEntityName+".set"+uppAttrName+"(DateUtil.now());";
                    hasHutoolDate = true;
                }else if("Date".equals(attrType)){
                    setValStr+="\n\t\t\t"+lowerEntityName+".set"+uppAttrName+"(new Date());";
                    hasDate = true;
                }
            }else if("updateTime".equals(attrName)){
                if("String".equals(attrType)){
                    setValStr+="\n\t\t\t"+lowerEntityName+".set"+uppAttrName+"(DateUtil.now());";
                    setDateKey = "\n\t\t\t"+lowerEntityName+".set"+uppAttrName+"(DateUtil.now());";
                    hasHutoolDate = true;
                }else if("Date".equals(attrType)){
                    setValStr+="\n\t\t\t"+lowerEntityName+".set"+uppAttrName+"(new Date());";
                    setDateKey = "\n\t\t\t"+lowerEntityName+".set"+uppAttrName+"(new Date());";
                    hasDate = true;
                }
            }
        }

        final String setPrimaryKey= setValStr;
        final String uuidPackage="String".equals(primaryKeyType)?"\nimport cn.hutool.core.lang.UUID;":"";
        final String hutoolDatePackage= hasHutoolDate==true?"\nimport cn.hutool.core.date.DateUtil;":"";
        final String utilDatePackage= hasDate==true?"\nimport java.util.Date;":"";
        final String setDateKeyStr= setDateKey;
        final String validateAttrNameStr= validateAttrName;
        Map<String,String> map = new HashMap<String,String>(){
            {
                put("filePackageName",packageName);
                put("entityPackage",entityPackName);
                put("exceptionPackage",exceptionPackName);
                put("dtoPackage",dtoPackName);
                put("listDtoPackage",listDtoPackage);
                put("voPackage",voPackName);
                put("commonBeanPackage",commonBeanPackage);
                put("upperEntityName",upperEntityName);
                put("tableComment",tableComment);
                put("projectAuthor",projInfo.getAuthor());
                put("nowDate", DateUtil.today());
                put("lowerEntityName",lowerEntityName);
                put("upperPrimaryKey",upperPrimaryKey);
                put("lowerPrimaryKey",lowerPrimaryKey);
                put("updateLowerPrimaryKey",updatePrimaryType);
                put("setPrimaryKey",setPrimaryKey);
                put("setDateKey",setDateKeyStr);
                put("uuidPackage",uuidPackage);
                put("enumsPackage",enumsPackage);
                put("utilDatePackage",utilDatePackage);
                put("hutoolDatePackage",hutoolDatePackage);
                put("utilsPackage",utilsPackage);
                put("validateAttrName",validateAttrNameStr);
                put("validatePackage",validatePackName);
                put("mapperPackage",mapperPackage);
                put("servicePackage",servicePackage);
                put("primaryType",primaryKeyType);
                put("primaryKeyComment",entityInfo.getPrimaryKeyComment());
            }
        };
        FileUtil.copyFile(projInfo,srcFilePath, destFilePath, map);
    }

}
